﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Eqwww.Domain.Models.Identity;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using Eqwww.App.Identity;
using Eqwww.Data;
using System.DirectoryServices;
using Eqwww.App.SystemManage;
using Eqwww.Code;

namespace Eqwww.Web.Areas.Identity.Pages.Account
{
    [AllowAnonymous]
    public class LoginModel : PageModel
    {
        private readonly SignInManager<UserModel> _signInApp;
        private readonly ILogger<LoginModel> _logger;
        private ApplicationDbContext _context;
        private UserApp _userApp;
        private DatabaseLogApp _databaseLogApp;

        private Eqwww.Config.IAppConfigProvider _appConfigProvider;

        public LoginModel(SignInManager<UserModel> signInApp, ILogger<LoginModel> logger, 
            ApplicationDbContext context, 
            UserApp userApp, 
            Eqwww.Config.IAppConfigProvider appConfigProvider,
            DatabaseLogApp databaseLogApp)
        {
            _signInApp = signInApp;
            _logger = logger;
            _context = context;
            _userApp = userApp;
            _appConfigProvider = appConfigProvider;
            _databaseLogApp = databaseLogApp;
        }

        [BindProperty]
        public InputModel Input { get; set; }

        public IList<AuthenticationScheme> ExternalLogins { get; set; }

        public string ReturnUrl { get; set; }

        [TempData]
        public string ErrorMessage { get; set; }

        public class InputModel
        {
            [Required(ErrorMessage = "本项不能为空")]
            [Display(Name = "账号")]
            public string Email { get; set; }

            [Required(ErrorMessage = "本项不能为空")]
            [DataType(DataType.Password)]
            [Display(Name = "密码")]
            public string Password { get; set; }

            [Display(Name = "RTX账户")]
            public bool RememberMe { get; set; }
        }

        public async Task OnGetAsync(string returnUrl = null)
        {
            if (!string.IsNullOrEmpty(ErrorMessage))
            {
                ModelState.AddModelError(string.Empty, ErrorMessage);
            }

            returnUrl = returnUrl ?? Url.Content("~/");

            // Clear the existing external cookie to ensure a clean login process
            await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);

            ExternalLogins = (await _signInApp.GetExternalAuthenticationSchemesAsync()).ToList();

            ReturnUrl = returnUrl;

        }

        public async Task<IActionResult> OnPostAsync(string returnUrl = null)
        {

            returnUrl = returnUrl ?? Url.Content("~/Manage");

            if (ModelState.IsValid)
            {
                var user = _userApp.FindByNameAsync(Input.Email).Result;
                if (user == null)
                {
                    return Content(Newtonsoft.Json.JsonConvert.SerializeObject(Eqwww.Code.Common.ErrorResult("用户不存在")));
                }

                var appConfig = _appConfigProvider.Load();
                if (user.IsDisabled == true)
                {
                    _databaseLogApp.LogInformationLogin(user.Id, "["+user.UserName+"]账号已被禁用");
                    return Content(Newtonsoft.Json.JsonConvert.SerializeObject(Eqwww.Code.Common.ErrorResult("账号已被禁用,如有疑问请联系管理员")));
                }

                if (Input.RememberMe)
                {
                    if (!appConfig.UseADLogin)
                    {
                        return Content((Eqwww.Code.Common.ErrorResult("系统已关闭AD域登录，请联系管理员。")).ToJson());
                    }

                    DirectoryEntry entry = null;
                    String sADPath = appConfig.ADPath;
                    entry = new DirectoryEntry(sADPath, Input.Email, Input.Password);
                    if (entry == null)
                    {
                        return Content(Newtonsoft.Json.JsonConvert.SerializeObject(Eqwww.Code.Common.ErrorResult("未找到指定AD账户")));
                    }
                    else
                    {

                        DirectorySearcher mySearcher = new DirectorySearcher(entry);
                        mySearcher.Filter = "(SAMAccountName=" + Input.Email + ")";
                        SearchResult result_ = null;
                        //开始AD校验
                        try
                        {
                            result_ = mySearcher.FindOne();
                        }
                        catch (Exception e)
                        {

                            return Content(Newtonsoft.Json.JsonConvert.SerializeObject(Eqwww.Code.Common.ErrorResult(e.Message+"_w")));
                        }
                        if (result_ == null)
                        {
                            return Content(Newtonsoft.Json.JsonConvert.SerializeObject(Eqwww.Code.Common.ErrorResult("未找到指定AD账户(1)")));
                        }
                        else
                        {
                            await _signInApp.SignInAsync(user, true);
                            Response.Cookies.Append("LastLoginUserId", user.Id, new Microsoft.AspNetCore.Http.CookieOptions
                            {
                                Expires = DateTime.Now.AddDays(30)
                            });
                            Response.Cookies.Append("CurrentUserIsRTX", user.UserType.ToString(), new Microsoft.AspNetCore.Http.CookieOptions
                            {
                                Expires = DateTime.Now.AddDays(30)
                            });
                            _logger.LogInformation("User logged in.");
                            return Content(Newtonsoft.Json.JsonConvert.SerializeObject(Eqwww.Code.Common.SuccessResult()));
                            
                        }

                    }
                }
                else
                {

                    var result = await _signInApp.PasswordSignInAsync(Input.Email, Input.Password, true, lockoutOnFailure: true);
                    if (result.Succeeded)
                    {

                        Response.Cookies.Append("LastLoginUserId", user.Id, new Microsoft.AspNetCore.Http.CookieOptions
                        {
                            Expires = DateTime.Now.AddDays(30)
                        });
                        Response.Cookies.Append("CurrentUserIsRTX", user.UserType.ToString(), new Microsoft.AspNetCore.Http.CookieOptions
                        {
                            Expires = DateTime.Now.AddDays(30)
                        });
                        _logger.LogInformation("User logged in.");
                        _databaseLogApp.LogInformationLogin(user.Id, "[" + user.UserName + "]登录成功！");
                        return Content(Newtonsoft.Json.JsonConvert.SerializeObject(Eqwww.Code.Common.SuccessResult()));
                    }
                    /*
                    if (result.RequiresTwoFactor)
                    {
                        return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe });
                    }
                    */
                    if (result.IsLockedOut)
                    {
                        _databaseLogApp.LogInformationLogin(user.Id, "["+user.UserName+ "]用户被锁定");
                        return Content(Newtonsoft.Json.JsonConvert.SerializeObject(Eqwww.Code.Common.ErrorResult("用户被锁定")));
                    }
                    else
                    {
                        _databaseLogApp.LogInformationLogin(user.Id, "[" + user.UserName + "]登录失败，账号或密码不正确。");
                        return Content(Newtonsoft.Json.JsonConvert.SerializeObject(Eqwww.Code.Common.ErrorResult("登录失败，请检查账号或密码是否正确")));

                    }
                }
            }

            return Content(Newtonsoft.Json.JsonConvert.SerializeObject(Eqwww.Code.Common.ErrorResult("用户名和密码不能为空!")));
        }
    }
}
